Popular Searches
Popular Course Categories
Popular Courses

Creating and Managing Multiple Activities

Creating and Managing Multiple Activities

Android Application Components and Lifecycle

Creating and Managing Multiple Activities in Android

Course: Android App Development

Topic: Creating and Managing Multiple Activities

Course Link: Android App Development Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to Multiple Activities in Android

An Android application often contains multiple screens that allow users to perform different tasks. For example, a shopping application may have a login screen, product list, product details screen, cart screen, and checkout screen. Android developers can use Activities to represent these individual screens or entry points into an application.

An Activity is an Android component that provides a window in which the application can display a user interface and interact with the user. Each Activity typically manages a particular screen or user interaction, although modern Android applications may also use fragments and Jetpack Compose navigation within an Activity.

Creating and managing multiple Activities involves defining Activity classes, designing their layouts, registering them in the application manifest, navigating between them using Intents, passing data, receiving results, and handling the Activity lifecycle.

2. Learning Objectives

After studying this topic, learners will be able to:

  • Understand the role of Activities in Android applications.
  • Create multiple Activity classes and their corresponding layouts.
  • Register Activities in AndroidManifest.xml.
  • Navigate between Activities using explicit Intents.
  • Pass data between Activities using Intent extras.
  • Receive results from another Activity using the Activity Result API.
  • Understand Activity lifecycle callbacks and state restoration.
  • Manage the Activity back stack and navigation behavior.
  • Apply appropriate Activity launch modes and flags.
  • Identify common navigation errors and follow Android development best practices.

3. What Is an Activity?

An Activity is an Android application component that provides an entry point for user interaction. It is commonly associated with a screen, although an application does not need to create a separate Activity for every screen.

For example, a student management application might use the following Activities:

  • LoginActivity: Allows users to enter their credentials.
  • DashboardActivity: Displays the main dashboard.
  • StudentListActivity: Displays registered students.
  • StudentDetailsActivity: Shows details of a selected student.
  • SettingsActivity: Allows users to modify application preferences.

3.1 Main Responsibilities of an Activity

  • Displaying a user interface.
  • Handling user interactions.
  • Starting other Activities when necessary.
  • Receiving and processing navigation data.
  • Managing UI-related state during lifecycle changes.
  • Coordinating with ViewModels, repositories, and other application components.

4. Understanding the Activity Lifecycle

Every Activity moves through a lifecycle as it is created, displayed, interrupted, stopped, and eventually destroyed. Understanding these lifecycle stages is essential when managing multiple Activities.

Lifecycle Method Purpose Typical Use
onCreate() Called when the Activity is created. Initialize variables, inflate the layout, configure listeners, and restore saved state.
onStart() Called when the Activity becomes visible. Prepare resources required while the Activity is visible.
onResume() Called when the Activity enters the foreground and becomes interactive. Resume UI-related work and interactions.
onPause() Called when the Activity is losing its resumed state. Pause ongoing interactions and release resources that should not remain active.
onStop() Called when the Activity is no longer visible. Stop work that is unnecessary while the screen is hidden.
onRestart() Called when a stopped Activity is about to start again. Prepare the Activity to become visible again.
onDestroy() Called when the Activity is being destroyed. Perform appropriate cleanup for resources owned by the Activity.

4.1 Typical Lifecycle Flow

Activity Created
      |
      v
  onCreate()
      |
      v
  onStart()
      |
      v
  onResume()
      |
      v
Activity in Foreground
      |
      v
   onPause()
      |
      v
    onStop()
      |
      +----------------------+
      |                      |
      v                      v
  onRestart()             onDestroy()
      |
      v
   onStart()
      |
      v
   onResume()

The actual sequence depends on how the Activity is used. For example, an Activity may receive onPause() without immediately receiving onStop() if another window partially covers it.

5. Creating a New Activity in Android Studio

Android Studio provides tools for creating Activity classes and layouts. The exact menu options may differ depending on the Android Studio version and project configuration.

5.1 Steps to Create an Activity

  1. Open your Android project in Android Studio.
  2. Navigate to the application source package under app/src/main/java or the corresponding Kotlin source directory.
  3. Right-click the package and choose the option to create a new Activity, if available.
  4. Select an appropriate Activity template or create a Kotlin class manually.
  5. Give the Activity a meaningful name, such as ProfileActivity.
  6. Create or configure its layout if using the XML View system.
  7. Ensure the Activity is declared in AndroidManifest.xml.
  8. Connect the Activity to the relevant navigation action.
  9. Run the application and verify that the new screen opens correctly.

5.2 Example Activity Class

package com.example.multiactivity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class ProfileActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_profile)
    }
}

This example uses AppCompatActivity and an XML layout named activity_profile.xml. Ensure that the AndroidX AppCompat dependency is included in the project. Projects using the platform Activity class or Jetpack Compose may use a different base class or UI setup.

6. Creating an XML Layout for an Activity

When using the XML View system, each Activity can have a layout file containing its UI components.

6.1 Example: activity_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="24dp">

    <TextView
        android:id="@+id/profileTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Profile Screen"
        android:textSize="24sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/profileDescription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:text="Welcome to your profile." />

</LinearLayout>

The layout uses a vertical LinearLayout with two TextViews. In larger projects, developers may prefer ConstraintLayout or other suitable layouts to create more flexible interfaces.

7. Registering Activities in AndroidManifest.xml

The Android manifest describes important information about an application, including its Activities, permissions, and application components. An Activity that is not automatically registered by the build tooling must be declared in the manifest.

7.1 Example Manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:label="Multi Activity App"
        android:theme="@style/Theme.MultiActivity">

        <activity
            android:name=".ProfileActivity"
            android:exported="false" />

        <activity
            android:name=".DashboardActivity"
            android:exported="false" />

        <activity
            android:name=".MainActivity"
            android:exported="true">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>

    </application>
</manifest>

In this example, MainActivity is the launcher Activity, while DashboardActivity and ProfileActivity are internal Activities. The android:exported attribute indicates whether other applications can launch the component directly, subject to Android's component-access rules.

When an Activity contains an intent filter, explicitly setting android:exported is required for applications targeting Android 12 (API level 31) or later. Use true only when external access is intended and the component is appropriately secured.

8. Understanding Intents

An Intent is a messaging object used to request an action from another Android component. Intents are commonly used to start Activities, start services, and deliver broadcast messages.

When navigating between Activities in the same application, developers commonly use explicit Intents. An explicit Intent identifies the target component directly.

8.1 Types of Intents

Type Description Example
Explicit Intent Specifies the target component. Opening ProfileActivity from MainActivity.
Implicit Intent Describes an action that another suitable component can handle. Opening a web page in a browser.

9. Navigating Between Two Activities

To open another Activity, create an Intent and pass it to startActivity().

9.1 MainActivity Kotlin Code

package com.example.multiactivity

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val openProfileButton =
            findViewById<Button>(R.id.openProfileButton)

        openProfileButton.setOnClickListener {
            val intent = Intent(this, ProfileActivity::class.java)
            startActivity(intent)
        }
    }
}

9.2 MainActivity Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="24dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Main Screen"
        android:textSize="24sp" />

    <Button
        android:id="@+id/openProfileButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Open Profile" />

</LinearLayout>

When the user taps the button, Android launches ProfileActivity. By default, the new Activity is placed on top of the current task's Activity back stack, allowing the user to return using the Back action.

10. Passing Data Between Activities

Applications often need to send information from one screen to another. For example, a product list may send a product ID to a product details screen. Intent extras provide a common mechanism for transferring small amounts of data.

10.1 Sending Data with Intent Extras

val intent = Intent(this, ProfileActivity::class.java)

intent.putExtra("USER_NAME", "Aarav")
intent.putExtra("USER_AGE", 25)

startActivity(intent)

The values are attached to the Intent before the target Activity is started.

10.2 Receiving Data in the Target Activity

class ProfileActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_profile)

        val userName =
            intent.getStringExtra("USER_NAME") ?: "Guest"

        val userAge =
            intent.getIntExtra("USER_AGE", 0)

        findViewById<TextView>(R.id.profileTitle).text =
            "Welcome, $userName"

        findViewById<TextView>(R.id.profileDescription).text =
            "Age: $userAge"
    }
}

Ensure that the appropriate TextView import is present:

import android.widget.TextView

Use consistent extra keys and suitable default values. For larger data structures, use supported Parcelable types or pass a stable identifier and load the full data from a repository instead of placing large objects into an Intent.

11. Using Constants for Intent Extra Keys

Repeatedly writing string keys can cause spelling mistakes. Defining constants makes the code easier to maintain.

object ProfileExtras {
    const val USER_NAME = "USER_NAME"
    const val USER_AGE = "USER_AGE"
}

Use the constants when sending data:

intent.putExtra(ProfileExtras.USER_NAME, "Aarav")
intent.putExtra(ProfileExtras.USER_AGE, 25)

Use the same constants when receiving it:

val name = intent.getStringExtra(ProfileExtras.USER_NAME)
val age = intent.getIntExtra(ProfileExtras.USER_AGE, 0)

This reduces the possibility of mismatched keys between Activities.

12. Returning Results from Another Activity

Sometimes an Activity must return a result to the screen that opened it. For example, a settings screen may allow the user to select a display preference. The modern recommended approach for many Activity-result use cases is the Activity Result API.

12.1 Registering an Activity Result Launcher

private val profileLauncher =
    registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->

        if (result.resultCode == RESULT_OK) {
            val message = result.data
                ?.getStringExtra("RESULT_MESSAGE")

            // Update the UI using the returned message.
        }
    }

Place this property in the Activity class, and add the relevant imports:

import android.app.Activity
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContracts

Launch the target Activity when required:

val intent = Intent(this, EditProfileActivity::class.java)
profileLauncher.launch(intent)

12.2 Returning the Result

In EditProfileActivity, return the result using an Intent:

val resultIntent = Intent().apply {
    putExtra("RESULT_MESSAGE", "Profile updated")
}

setResult(Activity.RESULT_OK, resultIntent)
finish()

Call this code after the relevant action has completed successfully, such as when the user taps Save. If the user cancels the operation, return an appropriate cancellation result or simply finish the Activity without reporting a successful update.

13. Understanding the Activity Back Stack

The Activity back stack stores the sequence of Activities in a task. When a new Activity is started normally, it is generally placed above the current Activity in the stack.

13.1 Example Navigation Sequence

MainActivity
     |
     v
DashboardActivity
     |
     v
ProfileActivity

The stack now contains MainActivity, DashboardActivity, and ProfileActivity, with ProfileActivity at the top.

When the user presses Back, ProfileActivity is normally finished, revealing DashboardActivity. Pressing Back again returns to MainActivity.

13.2 finish() Method

The finish() method closes the current Activity and removes its instance from the current task's back stack.

finish()

For example, after a user completes a temporary editing screen, calling finish() can return the user to the previous Activity. Do not call it automatically after every navigation action; the correct behavior depends on the intended user flow.

14. Managing Activity State

Android may recreate an Activity after configuration changes, such as device rotation, or when the operating system needs to reclaim resources. Important UI state should not depend exclusively on the lifetime of a single Activity instance.

14.1 Saving Small Amounts of State

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)

    outState.putString("SEARCH_QUERY", currentSearchQuery)
    outState.putInt("SELECTED_TAB", selectedTabIndex)
}

14.2 Restoring State

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    currentSearchQuery =
        savedInstanceState?.getString("SEARCH_QUERY").orEmpty()

    selectedTabIndex =
        savedInstanceState?.getInt("SELECTED_TAB") ?: 0
}

The variables in this example must be declared in the Activity class. Saved instance state is appropriate for small pieces of transient UI state. Persistent application data should be stored using an appropriate data-storage solution, and longer-lived screen state is often managed through a ViewModel.

15. Activity Launch Modes

Launch modes influence how Android creates or reuses Activity instances when navigation occurs. They should be selected according to a clear navigation requirement rather than applied indiscriminately.

Launch Mode General Behavior Common Use
standard Creates a new Activity instance for each launch under normal task rules. Ordinary screens that can have multiple instances.
singleTop Reuses the Activity if the target instance is already at the top of the task. Avoiding a duplicate top instance in suitable navigation flows.
singleTask Uses task-level rules to locate or create an instance and may clear Activities above an existing instance. Special task and deep-link navigation requirements.
singleInstance Applies specialized task isolation behavior. Uncommon cases requiring a separate task arrangement.

Launch behavior also depends on the task, Intent flags, document mode, and Android version. For most ordinary application screens, the default standard mode is appropriate.

16. Intent Flags and Navigation Control

Intent flags can modify how an Activity is launched or how the task stack is handled.

16.1 FLAG_ACTIVITY_CLEAR_TOP

This flag can bring an existing target Activity to the top and remove Activities above it in the applicable task, subject to the Activity's launch mode and other flags.

val intent = Intent(this, DashboardActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(intent)

16.2 FLAG_ACTIVITY_SINGLE_TOP

This flag can avoid creating another instance when the target Activity is already at the top of the task.

val intent = Intent(this, DashboardActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)

When an existing Activity instance is reused, it may receive the new Intent through onNewIntent(). Handle this callback when the Activity must process updated navigation data.

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent)

    // Process the new Intent and refresh relevant state.
}

17. Handling Back Navigation

Back navigation allows users to return to a previous screen or leave the current navigation flow. Developers should preserve expected Android navigation behavior and avoid intercepting Back unnecessarily.

17.1 Finishing the Current Activity

backButton.setOnClickListener {
    finish()
}

This is useful when a custom in-app button should close the current Activity.

17.2 Handling Back Actions

Modern Android applications can use the AndroidX OnBackPressedDispatcher and the appropriate callback API for custom Back behavior. Custom behavior should be limited to cases where the application has a clear need, such as dismissing an open panel before leaving a screen.

For ordinary Activity navigation, allowing Android to handle Back automatically is usually the simplest and most reliable approach.

18. Using Multiple Activities with RecyclerView

A common Android pattern is to display a list of items in one Activity and open a details Activity when the user selects an item.

18.1 Passing a Selected Item ID

fun openStudentDetails(studentId: Int) {
    val intent = Intent(this, StudentDetailsActivity::class.java)
    intent.putExtra("STUDENT_ID", studentId)
    startActivity(intent)
}

Call openStudentDetails() from the appropriate RecyclerView item click callback.

18.2 Loading the Selected Item

class StudentDetailsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_student_details)

        val studentId = intent.getIntExtra("STUDENT_ID", -1)

        if (studentId == -1) {
            finish()
            return
        }

        // Load the student from a repository using studentId.
    }
}

This approach sends a small identifier rather than the entire student record. The destination can retrieve the latest information from a repository or database.

19. Common Problems When Managing Multiple Activities

Problem Possible Cause Solution
Activity does not open Incorrect class reference, missing manifest declaration, or an invalid navigation call. Check the Intent target, Activity declaration, and Logcat output.
Application crashes when reading extras Incorrect key, unexpected data type, or missing required value. Use consistent keys, validate input, and provide appropriate fallback behavior.
Duplicate screens appear Repeated launches or an unsuitable navigation strategy. Review the user flow before choosing launch modes or Intent flags.
Back button returns to an unexpected screen The task stack has been modified or the navigation flow was not designed consistently. Review Activity launches, finish() calls, and Intent flags.
Data disappears after rotation Transient UI state was stored only in Activity fields. Use saved instance state, ViewModel, or persistent storage as appropriate.
Activity is recreated unexpectedly Configuration changes, system resource reclamation, or other lifecycle events. Make initialization repeatable and restore the required UI state.
Manifest installation or launch error Invalid manifest configuration or missing exported settings for applicable components. Validate AndroidManifest.xml and configure android:exported correctly.
Memory leak involving an Activity A long-lived object retains an Activity reference after its lifecycle ends. Avoid unnecessary static references and clean up lifecycle-bound resources.

20. Best Practices for Multiple Activity Management

  • Give each Activity a clear responsibility.
  • Use meaningful names such as LoginActivity, DashboardActivity, and SettingsActivity.
  • Register Activities correctly in AndroidManifest.xml.
  • Use explicit Intents for navigation to known internal Activities.
  • Use consistent keys and validate incoming Intent data.
  • Pass identifiers instead of unnecessarily large objects.
  • Use the Activity Result API when a launched Activity must return a result.
  • Preserve important state across configuration changes and process recreation.
  • Use the default launch mode unless a specific requirement justifies another mode.
  • Avoid starting Activities repeatedly in response to the same event.
  • Follow the Android lifecycle when managing listeners, resources, and UI-related work.
  • Keep business logic outside Activities where practical, using ViewModels and repositories.
  • Test navigation, Back behavior, device rotation, and process recreation.
  • Consider whether a single Activity with Navigation Component or Jetpack Compose navigation would be simpler for a multi-screen application.

21. Practical Project: Student Management Application

Create a simple Android application that demonstrates navigation between multiple Activities.

Project Requirements

  • MainActivity: Displays a welcome message and navigation buttons.
  • StudentListActivity: Displays a list of students.
  • StudentDetailsActivity: Displays details for a selected student.
  • SettingsActivity: Displays application settings.

Implementation Steps

  1. Create the required Activity classes and XML layouts.
  2. Register the Activities in AndroidManifest.xml.
  3. Add buttons or list item click listeners to MainActivity.
  4. Use explicit Intents to open the student list and settings screens.
  5. Pass a student ID from StudentListActivity to StudentDetailsActivity.
  6. Load the matching student information in the details screen.
  7. Implement appropriate Back navigation.
  8. Test lifecycle behavior by rotating the device and returning to previously visited screens.

Expected Outcome

The finished application should allow users to move between screens, view selected student information, return to previous screens, and maintain important UI state when appropriate.

22. Testing Multiple Activities

Testing ensures that navigation and data transfer work correctly under normal and unusual conditions.

  • Verify that every navigation button opens the intended Activity.
  • Confirm that Intent extras arrive with the expected values.
  • Test behavior when optional data is missing.
  • Press Back from every screen and verify the expected destination.
  • Rotate the device and check whether important state is restored.
  • Test repeated navigation to identify accidental duplicate screens.
  • Check AndroidManifest.xml for correct Activity declarations.
  • Use Logcat to diagnose exceptions and lifecycle issues.
  • Test on an emulator and, where possible, a physical Android device.

23. Interview Questions and Answers

Q1. What is an Activity in Android?

An Activity is an Android component that provides a window for user interaction and can serve as an entry point into an application.

Q2. How do you create a new Activity?

Create an Activity class, configure its UI, register it in the manifest when necessary, and launch it using an Intent.

Q3. What is an Intent?

An Intent is a messaging object used to request an action from another Android component, such as starting an Activity.

Q4. What is the difference between explicit and implicit Intents?

An explicit Intent identifies a target component, whereas an implicit Intent describes an action that a suitable component can handle.

Q5. How can you pass data between Activities?

Use Intent extras to pass supported values, such as strings, integers, and appropriate Parcelable data.

Q6. What is the Activity back stack?

It is the stack of Activity instances within a task that generally determines which Activity becomes visible when the user navigates Back.

Q7. What does finish() do?

The finish() method requests that the current Activity be closed and removed from its task.

Q8. What is the purpose of onCreate()?

It initializes an Activity instance, sets up its interface, and restores appropriate saved state.

Q9. What is the Activity Result API?

It is a modern Android API that allows a component to launch another Activity or supported operation and handle the returned result through a registered callback.

Q10. What is a launch mode?

A launch mode defines rules that influence whether Android creates or reuses an Activity instance and how it participates in task navigation.

Q11. Why is android:exported important?

It controls whether other applications can directly launch a component, subject to Android's security and component-resolution rules.

Q12. How can Activity state be preserved?

Use saved instance state for small transient UI values, ViewModel for appropriate screen state, and persistent storage for data that must survive beyond the current screen or process.

24. Quick Revision Checklist

  • An Activity is a fundamental Android component for user interaction.
  • Multiple Activities can represent different application screens.
  • Activity declarations and exported settings belong in the manifest when required.
  • Explicit Intents are commonly used to launch internal Activities.
  • Intent extras transfer data between Activities.
  • The Activity Result API handles returned results.
  • The Activity lifecycle controls initialization, visibility, and cleanup.
  • The back stack determines ordinary Back navigation within a task.
  • Launch modes and Intent flags modify Activity navigation behavior.
  • Saved instance state and ViewModels help preserve appropriate UI state.
  • Testing navigation and lifecycle behavior helps prevent common application errors.

25. Conclusion

Creating and managing multiple Activities is an important part of Android application development. By understanding Activity classes, manifest configuration, Intents, data transfer, lifecycle callbacks, and back-stack behavior, developers can create applications with predictable and user-friendly navigation.

For maintainable applications, each Activity should have a clear purpose, navigation data should be validated, and important state should be handled appropriately. Developers should also consider modern single-Activity navigation approaches when these better fit the application's architecture.

Continue learning through the Android App Development course at JustAcademy, visit the JustAcademy website, or register for a course demo.

Previous Next
whatsapp